//C++中所有的值不是左值就是右值，左值指表达式结束后依然存在的持久化对象
//右值值表达式结束后就不再存在的临时对象。有名字的对象就是左值，右值没有名字

//或者说，能取地址就是左值，不能则是右值

//一般说的引用就是左值引用
//右值引用就是给右值取一个名字,让他成为一个普通变量(左值)，可以像使用左值一样使用他
	//语法: 数据类型&& 变量名= 右值
#include<iostream>
#include<vector>
#include<functional>
using namespace std;

class AA
{
public:
	int m_a = 9;
};

AA getTemp()
{
	return AA();	//返回AA类的匿名对象
}
int main()
{
	int&& a = 3;	//3是右值，取名为a
	int b = 8;		//b是左值
	int&& c = b + 5;	//b+5是右值，取名为c
	AA&& aa = getTemp();	//getTemp()的返回值是右值(临时变量)

	cout << "a = " << a << endl;
	cout << "c = " << c << endl;
	cout << "aa.m_a = " << aa.m_a << endl;		//取了名字的右值可以像左值一样输出
	return 0;
}



//C++引入右值引用的主要目的是实现移动语义

//左值引用(&)只能绑定左值，右值引用(&&)只能绑定右值
int& a = 3;		//会报错(左值引用绑定右值)
int b = 3;
int&& c = b;	//会报错(右值引用绑定左值)
int&& x = 10;
int&& y = x;	//会报错(x被右值引用后变成左值，不能再被右值引用绑定)




//特列——常量左值引用
//可以算是一个万能的引用类型，可以绑定左值和右值，而且绑定右值时同样将其变为左值
//缺点是只能读，不能修改
int a = 1;
const int& ra = a;	//a是非常量左值

const int b = 1;
const int& rb = b;	//b是常量左值

const int& rc = 1;	//1是右值